package ferp.center.server.servlet;

import ferp.center.network.RequestGameResult;
import ferp.center.network.ResponseGameResult;
import ferp.center.server.Action;
import ferp.center.server.entity.Profile;
import ferp.center.server.entity.Rating;
import ferp.center.server.task.TaskRangeTreeUpdate;
import ferp.core.Version;
import ferp.core.util.Convert;

import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

/**
 * User: igorgok
 * Date: 5/10/12 1:30 PM
 */
public class GameAdd extends HttpServlet
{
  protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  {
    Action.execute(request, response, RequestGameResult.class, new Action.Write<RequestGameResult, ResponseGameResult>()
    {
      @SuppressWarnings("unchecked")
      public ResponseGameResult run(EntityManager em, RequestGameResult input) throws IOException
      {
        ResponseGameResult result = new ResponseGameResult();
        Profile p = em.find(Profile.class, input.profile);

        if (p != null)
        {
          // update accessed field of the profile
          p.setAccessed(new Date());

          // adjust configuration code for old clients
          if (input.version == null || input.configuration.length() < 6)
          {
            input.configuration = Convert.configuration(input.configuration);

            log("old configuration code changed to [" + input.configuration + "]");
          }

          // only for the latest versions
          if (input.version != null && input.version.code >= Version.LATEST)
          {
            // find and update an appropriate rating
            // convert rating configuration on the fly
            Rating r = p.getRating(input.configuration);

            if (r != null)
            {
              assign(r, p, input);
              // rise "updated" flag
              result.updated = true;
            }
            else
            {
              // create new rating record
              r = new Rating();

              assign(r, p, input);
              p.getRatings().add(r);
              em.persist(r);
              em.refresh(r);

              // rise "added" flag
              result.added = true;
            }

            // queue task for range tree update
            TaskRangeTreeUpdate.queue(r);
          }
          else
            log("version mismatch: " + (input.version == null ? "ancient" : String.valueOf(input.version.code)) + " vs required " + Version.LATEST + " and up");
        }

        return result;
      }
    });
  }

  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
  {

  }

  private static Rating assign(Rating r, Profile p, RequestGameResult request)
  {
    r.setProfile(p);
    r.setConfiguration(request.configuration);
    r.setSpeed(request.speed);
    r.setGames(request.games);
    r.setPool(request.pool);
    r.setCash(request.cash);
    // calculate rating - currently use total cash
    r.setValue(request.cash);

    return r;
  }
}
